from flask import Response, current_app, json, jsonify, Blueprint
from flask_restful import Resource, reqparse, Api
from common.utils.login_token import _generate_token
import time, base64, hmac, requests
import urllib, redis
from urllib.parse import parse_qs
from common.models.users import *
from defaults.dev import *
from werkzeug.security import check_password_hash



oauth_user_bp = Blueprint("oauth_user", __name__, url_prefix="/oauth")
api = Api(oauth_user_bp)

class rds():
    def redis(self):
        # 链接redis
        rds = redis.Redis(host=DevDefaultConfig.REDIS_HOST,port=DevDefaultConfig.REDIS_POST,
                          db=DevDefaultConfig.REDIS_DB,password=DevDefaultConfig.REDIS_PASSWORD)
        return rds

class Dingding(Resource):
    def get_ding_user(self, code):
        base_url = "https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature="
        appid = current_app.config.get('DING_APP_ID')
        appSecret = current_app.config.get('DING_SECRET_KEY')

        # 定义时间
        # 并将其转换为str格式和毫秒
        timestamp = str((int(round(time.time()*1000))))

        # 对第三方的secret信息和时间进行加密和编码生成路由
        signature = base64.b64encode(hmac.new(appSecret.encode('utf-8'), timestamp.encode('utf-8'), digestmod="sha256").digest())

        # 拼接url
        url = base_url + urllib.parse.quote(signature.decode('utf-8')) + "&timestamp="+timestamp + "&accessKey=" + appid
 
        resp = requests.post(url, data=json.dumps({'tmp_auth_code':code}), headers={'Content-Type': 'application/json'})

        # 将对象转换更json格式并返回
        return resp.json()
 
    def get(self):
        # 根据前端传来的code, 获取钉钉登录的用户信息
        parser = reqparse.RequestParser()
        parser.add_argument('code')
        args = parser.parse_args()
        code = args.get('code')
 
        # 根据code获取钉钉用户信息
        ding_user = self.get_ding_user(code)

        # 对钉钉的用户信息进行验证
        if ding_user['errcode'] != 0:
            return jsonify(msg="获取信息失败", code=500)
        # 获取钉钉的openid
        openid = ding_user['user_info']['openid']

        # 判断openid
        if openid:
            # 根据openid 判定是否绑定账号
            oauth_user = OauthUser.query.filter_by(user=openid).first()
            if oauth_user:
                # 查询到用户,已经绑定过,
                user = UserModel.query.filter_by(uid=oauth_user.user).first()
                # 返回绑定成功的用户token 及id
                token = _generate_token({'account': user.account,'user_id': user.uid, 'is_superuser': user.is_superuser})
 
                return jsonify(msg="登陆成功", data={'code': 200, 'token': token, 'account': user.account, 'uid': user.uid})
            else:
                # 没有绑定需要进行绑定
                return jsonify(msg="没有绑定用户,请先绑定", data={'uid':openid} )


class DingdingBindUser(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument("account")
        parser.add_argument("password")
        parser.add_argument("unid")
        args = parser.parse_args()
        account = args.get('account')
        password = args.get('password')
        user_id = args.get('unid')

        try:
            print("????????????????", account, password, user_id)
            user = User.query.filter_by(uname=account).first()
        except Exception as e:
            print("1>>>>>>>>>>>",e)
            return jsonify(code=200)

        print(">>>>>>>>>>>>>>>>user", user)
        if not user:
            return jsonify(message="用户名不存在", code=400)
        else:
            users_oauth = OauthUser(oauth_id=user_id,user=user.uid,oauth_type="dingding")
            db.session.add(users_oauth)
            db.session.commit()
            token = _generate_token({'account': user.account,'user_id': user.uid})
            return jsonify(msg="登陆成功",data={'code': 200,'token': token,'account': user.account,'uid': user.uid})


class WeiboResource(Resource):
    def get(self):
        """根据code 获取微博用户信息"""
        parser = reqparse.RequestParser()
        parser.add_argument('code')
        args = parser.parse_args()
        # 1.获取code值
        code = args.get('code')
        # 构造参数获取weibo的用户信息
        base_url = 'https://api.weibo.com/oauth2/access_token'

        data_ = {"client_id":"2775107052", "client_secret" : "718b38b04fc387700cc1595b30875b19", "grant_type": code}

        resp = requests.post(base_url,data=json.dumps(data_))
        print("resp>>>>>>>>>>>>>>>>>>", resp.json())

        # 获取唯一的凭证
        access_token = resp.json()['access_token']

        oauther_user = OauthUser.query.filter_by(oauth_id = access_token, oauth_type='seibo').first()
        if oauther_user:
            user = User.query.filter_by(uid=oauther_user.user).first()

            data = {
                "uid": user.uid,
                "username": user.account
            }
            token, refresh_token = _generate_token(payload = data)
            return jsonify()
        else:
            return jsonify()



class OauthWeiboLogin(Resource):
    def get_weibo_user(self, code):
        data_ = {
            "client_id": "2775107052",
            "client_secret": "718b38b04fc387700cc1595b30875b19",
            "grant_type": "authorization_code",
            "redirect_uri": "http://127.0.0.1:8080/weibo",
            "code": code,
        }
        base_url = "https://api.weibo.com/oauth2/access_token"
        try:
            resp = requests.post(url=base_url, data=data_).json()
            print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>resp", resp)
        except Exception as e:
            return {"message": "获取微博用户信息失败", "code": 400}

        if not resp["access_token"]:
            return {"message": "根据code获取钉钉用户信息失败", "code": 400}
        else:
            user_dict = resp
            return user_dict

    def get(self):
        parser = reqparse.RequestParser()
        parser.add_argument("code")
        args = parser.parse_args()
        code = args["code"]
        user_dict = self.get_weibo_user(code)
        access_token = user_dict["access_token"]
        oauth_user = OauthUser.query.filter_by(uid=access_token, oauth_type="weibo").first()
        if oauth_user:
            user = User.query.filter_by(uid=oauth_user.user).first()
            # payload = {"uid": user.uid}
            # token = _generate_token(payload)
            data_ = {
                "account": user.account,
                "id": user.uid,
                # "token": token
            }
            return {"message": "登录成功", "code": 200, "data": data_}
        else:
            return {"message": "用户没有绑定，请先绑定", "code": 500, "uid": access_token}

class WeiboBindUser(Resource):
    def post(self):
        parser = reqparse.RequestParser()
        parser.add_argument("account")
        parser.add_argument("password")
        parser.add_argument("unid")
        args = parser.parse_args()
        account = args["account"]
        password = args["password"]
        unid = args["unid"]
        print("------->unid", unid)
        user = User.query.filter_by(account=account).first()
        if not user:
            return {"message": "用户未注册，请先注册", "code": 400}

        else:
            if not check_password_hash(user.password, password):
                return {"message": "密码错误", "code": 400}
            else:
                oauth_user = OauthUser(uid=unid, user=user.uid, oauth_type="weibo")
                db.session.add(oauth_user)
                db.session.commit()
                # payload = {"uid": user.uid}
                # token = _generate_token(payload)
                data_ = {
                    "uid": user.uid,
                    "account": user.account,
                    # "token": token,
                }
                return {"message": "绑定成功", "code": 200, "data": data_}


api.add_resource(Dingding, "/dingding")
api.add_resource(DingdingBindUser, "/dingding/bind")

